import axios, { AxiosError } from "axios";
import ip from "ip";
import { SvnHolder } from "../core/SvnHolder.js";
import { Hudson } from "./hudson.js";
import moment from "moment";

export class Alert {

    private static ins: Alert;
    public static get Instance(): Alert {
        if(!Alert.ins) Alert.ins = new Alert();
        return Alert.ins;
    }

    private chatid: string | null = null;
    public setChatId(chatid: string): void {
        this.chatid = chatid;
    }

    private async makeBuildReport(success: boolean, content: string, appendLogURL: boolean): Promise<feishu.ICardMessagePayload> {
        const startUser = await Hudson.getStartUser();
        const jobDesc = `${Hudson.getJobName()} #${Hudson.getBuildNumber()}`;
        const elements: feishu.IMsgElement[] = [
            {
                "tag": "markdown",
                "content": `时间: ${moment().format(moment.HTML5_FMT.TIME)}`,
                "text_align": "left",
                "text_size": "normal",
                "icon": {
                    "tag": "standard_icon",
                    "token": "time_outlined",
                    "color": "grey"
                }
            }
        ];
        if (content) {
            elements.push({
                "tag": "markdown",
                content,
                "text_align": "left",
                "text_size": "normal",
                "icon": {
                    "tag": "standard_icon",
                    "token": "warning_filled",
                    "color": "red"
                }
            });
        }
    
        const link = `http://builder.fygame.com:8282/hudson/job/${Hudson.getJobName()}/${Hudson.getBuildNumber()}/consoleText`;
        if (appendLogURL) {
            elements.push({
                "tag": "markdown",
                "content": `[点击查看构建日志](${link})`,
                "text_align": "left",
                "text_size": "normal"
            });
        }
        return {
            "config": {
                "update_multi": true
            },
            "card_link": {
                "url": link
            },
            "i18n_elements": {
                "zh_cn": elements
            },
            "i18n_header": {
                "zh_cn": {
                    "title": {
                        "tag": "plain_text",
                        "content": success ? `☀️${jobDesc}构建成功` : `🌧️${jobDesc}构建失败`
                    },
                    "subtitle": {
                        "tag": "plain_text",
                        "content": `@${startUser}`
                    },
                    "template": success ? "green" : "red"
                }
            }
        };
    }

    public async sendBuildFailureAlert(msg: string): Promise<void> {        
        console.error(msg);
        if (!this.chatid) return;
        const report = await this.makeBuildReport(false, msg, true);    
        // 先群发消息
        await this.sendRobotMsgInternal({
            chatid: this.chatid,
            payload: {
                msg_type: 'interactive',
                content: report
            }
        });
    }

    public async alertErrorFile(file: string, sendToUser = false): Promise<void> {
        if (!sendToUser && !this.chatid) return;

        const info = await SvnHolder.Instance.svnClient.info([file], { showItem: 'last-changed-author' });
        const touser = info.trim();

        if (sendToUser) {
            await this.sendRobotMsgInternal({
                ename: touser,
                payload: {
                    msg_type: 'text',
                    content: JSON.stringify({ text: `文件错误，速改！\n${file}` })
                }
            });
            return;
        } else {
            await this.sendRobotMsgInternal({
                chatid: this.chatid!,
                payload: {
                    msg_type: 'text',
                    content: JSON.stringify({ text: `文件错误，速改！\n${file}` })
                },
                mention: [touser]
            });
        }
    }

    public async sendTextMsg(msg: string, replyTo?: string): Promise<void> {
        if (!this.chatid) return;

        await this.sendRobotMsgInternal({
            chatid: this.chatid,
            reply_id: replyTo,
            payload: {
                msg_type: 'text',
                content: JSON.stringify({ text: msg })
            }
        });
    }
    
    private makeRobotMsgPayload(type: 'text' | 'markdown' | 'file' | 'image', msg: string): feishu.IMsgPayload | null {
        if (type == 'text') {
            return {
                msg_type: 'text',
                content: JSON.stringify({ text: msg })
            }
        }
        if (type == 'markdown') {
            // markdown格式将转为飞书卡片
            return {
                msg_type: 'interactive',
                content: {
                    "config": {
                        "update_multi": true
                    },
                    "card_link": {
                        "url": ""
                    },
                    "i18n_elements": {
                        "zh_cn": [
                            {
                                "tag": "markdown",
                                "content": msg,
                                "text_align": "left",
                                "text_size": "normal"
                            }
                        ]
                    },
                    "i18n_header": {}
                }
            }
        }
        if (type == 'file') {
            return {
                msg_type: 'file',
                content: {
                    file_key: msg
                }
            }
        }
        if (type == 'image') {
            return {
                msg_type: 'image',
                content: {
                    image_key: msg
                }
            }
        }
        console.error('msg type not supported!');
        return null;
    }
    
    private async sendRobotMsgInternal(payload: feishu.IRobotMsgPost): Promise<feishu.IBaseResponse> {
        const url = 'http://localhost:3000/api/app/robotmsg';
        const result = await axios.post<feishu.IBaseResponse>(url, { data: payload }, { timeout: 3000, proxy: false }).catch((e) => {
            console.error('Exception when post robot msg:', url, e instanceof Error ? e.stack : e.toString());
            let msg: string;
            if (e instanceof Error) {
               msg = e.message;
               const d = (e as AxiosError<feishu.IBaseResponse>).response?.data;
               if (d) {
                   msg += `, data: ${JSON.stringify(d)}`;
               }
            } else {
                msg = e.toString();
            }
            console.error(msg);
            return { data: { code: -1, msg }}
        });
        if (result.data.code != 0) {
            console.error(`robot msg sent failed: ${result.data.msg}, payload:`, payload);
        }
        // console.log('robot msg sent success:', payload, result);
        return result.data;
    }
}